/*
 * @Author: 缄默
 * @Date: 2021-12-12 15:18:42
 * @LastEditors: 缄默
 * @LastEditTime: 2022-02-09 17:59:57
 */

//模板方法模式

#include <iostream>
#include <vector>

using namespace std;


class TemplateMethd {
public:
    //控制打印的流程
    virtual void  printCase() final {
        print1();
        if (hook1()) {
            print2();
        }
        else {
            print3();
        }
    }


protected:
    virtual void print1() = 0;

    virtual void print2() = 0;

    virtual void print3() = 0;

    //留出钩子函数让子类可以重写
    virtual bool hook1() {
        return true;
    }
};

class ConcreteMethod1 : public TemplateMethd {
protected:
    void print1() {
        cout << " print1() is called ..." << endl;
    }

    void print2() {
        cout << " print2() is called ..." << endl;
    }

    void print3() {
        cout << " print3() is called ..." << endl;
    }
};

class ConcreteMethod2 : public TemplateMethd {
protected:

    //子类继承时可以单独实现相应方法
    void print1() {
        cout << " method is changed ..." << endl;
    }

    void print2() {
        cout << " print2() is called ..." << endl;
    }

    
    void print3() {
        cout << " print3() is called ..." << endl;
    }

    //子类可以通过重写hook（）函数反向控制父类函数的走向
    bool hook1() {
        return false;
    }
};

int main() {
    TemplateMethd* tem1 = new ConcreteMethod1();
    tem1->printCase();

    TemplateMethd* tem2 = new ConcreteMethod2();
    tem2->printCase();

    delete tem1;
    delete tem2;
    return 0;
}
